using System;
using System.IO.Ports;
using System.Windows.Forms;

namespace WorkerService1
{
    public partial class MainForm : Form
    {
        private SerialPort _serialPort;
        private ComboBox cmbPort;
        private ComboBox cmbBaudRate;
        private ComboBox cmbStopBits;
        private ComboBox cmbParity;
        private TextBox txtMessage;
        private RichTextBox txtHistory;
        private Label lblStatus;
        private Button btnSend;
        private Button btnApply;

        public MainForm(string portName)
        {
            InitializeControls();
            LoadComboBoxData();
            LoadAvailablePorts();
            InitializeSerialPort(portName);
        }

        // 1. 初始化控件
        private void InitializeControls()
        {
            this.Text = "串口通信工具";
            this.Size = new System.Drawing.Size(450, 450);

            cmbPort = new ComboBox { Location = new System.Drawing.Point(10, 10), Width = 100 };
            cmbBaudRate = new ComboBox { Location = new System.Drawing.Point(120, 10), Width = 100 };
            cmbStopBits = new ComboBox { Location = new System.Drawing.Point(10, 40), Width = 100 };
            cmbParity = new ComboBox { Location = new System.Drawing.Point(120, 40), Width = 100 };
            txtMessage = new TextBox { Location = new System.Drawing.Point(10, 70), Width = 300 };
            txtHistory = new RichTextBox { Location = new System.Drawing.Point(10, 100), Size = new System.Drawing.Size(400, 200), ReadOnly = true };
            lblStatus = new Label { Location = new System.Drawing.Point(10, 310), Text = "状态: 未连接", AutoSize = true };
            btnSend = new Button { Location = new System.Drawing.Point(10, 340), Text = "发送", Width = 80 };
            btnApply = new Button { Location = new System.Drawing.Point(100, 340), Text = "应用设置", Width = 80 };

            // 添加控件到窗体
            this.Controls.Add(cmbPort);
            this.Controls.Add(cmbBaudRate);
            this.Controls.Add(cmbStopBits);
            this.Controls.Add(cmbParity);
            this.Controls.Add(txtMessage);
            this.Controls.Add(txtHistory);
            this.Controls.Add(lblStatus);
            this.Controls.Add(btnSend);
            this.Controls.Add(btnApply);

            // 绑定事件
            btnSend.Click += BtnSend_Click;
            btnApply.Click += BtnApply_Click;
        }

        // 2. 加载下拉框数据
        private void LoadComboBoxData()
        {
            cmbBaudRate.Items.AddRange(new object[] { 9600, 19200, 38400, 57600, 115200 });
            cmbBaudRate.SelectedIndex = 0;

            cmbStopBits.Items.AddRange(new object[] { "1", "1.5", "2" });
            cmbStopBits.SelectedIndex = 0;

            cmbParity.Items.AddRange(new object[] { "None", "Even", "Odd" });
            cmbParity.SelectedIndex = 0;
        }

        // 3. 加载可用串口
        private void LoadAvailablePorts()
        {
            string[] ports = SerialPort.GetPortNames();
            cmbPort.Items.AddRange(ports);
            if (ports.Length > 0)
                cmbPort.SelectedIndex = 0;
        }

        // 4. 初始化串口
        private void InitializeSerialPort(string portName)
        {
            _serialPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One)
            {
                Handshake = Handshake.None,
                ReadTimeout = 500,
                WriteTimeout = 500
            };
            _serialPort.DataReceived += DataReceivedHandler;
        }

        // 5. 数据接收事件
        private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            string data = _serialPort.ReadExisting();
            string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            this.Invoke(new Action(() =>
            {
                txtHistory.AppendText($"[RECV {timestamp}] {data}\n");
            }));
        }

        // 6. 发送消息
        private void BtnSend_Click(object sender, EventArgs e)
        {
            if (!_serialPort.IsOpen)
            {
                MessageBox.Show("请先应用串口设置！");
                return;
            }

            string message = txtMessage.Text;
            if (string.IsNullOrEmpty(message)) return;

            string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            string formattedMessage = $"[SENT {timestamp}] {message}";

            try
            {
                _serialPort.WriteLine(formattedMessage);
                txtHistory.AppendText($"{formattedMessage}\n");
                txtMessage.Clear();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送失败: {ex.Message}");
            }
        }

        // 7. 应用设置
        private void BtnApply_Click(object sender, EventArgs e)
        {
            if (_serialPort.IsOpen)
                _serialPort.Close();

            _serialPort.PortName = cmbPort.SelectedItem.ToString();
            _serialPort.BaudRate = int.Parse(cmbBaudRate.SelectedItem.ToString());
            _serialPort.StopBits = cmbStopBits.SelectedItem.ToString() switch
            {
                "1" => StopBits.One,
                "1.5" => StopBits.OnePointFive,
                "2" => StopBits.Two,
                _ => StopBits.One
            };
            _serialPort.Parity = cmbParity.SelectedItem.ToString() switch
            {
                "None" => Parity.None,
                "Even" => Parity.Even,
                "Odd" => Parity.Odd,
                _ => Parity.None
            };

            try
            {
                _serialPort.Open();
                lblStatus.Text = "状态: 已连接";
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("权限不足，请以管理员身份运行程序！");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"错误: {ex.Message}");
            }
        }

        // 8. 关闭窗体时释放资源
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            if (_serialPort.IsOpen)
                _serialPort.Close();
            _serialPort.Dispose();
            base.OnFormClosing(e);
        }
    }
}